import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
 * JDBC默认情况下对事务是怎么处理的？
 *  模拟一个银行账户转账，A账户向B账户转账10000元。
 *  从A账户减去10000，向B账户加上10000
 *  必须同时成功，或者同时失败
 *
 *  转账需要执行两条update语句
 *
 *  //jdbc默认执行自动提交：
 *        就是执行一条语句就提交一次语句。
 *    在实际开发中必须将jdbc的自动提交机制关闭掉，改为手动提交，
 *  当一个完整的事务结束之后，再提交。
 *   conn.setAutoCommit(false);关闭自动提交机制
 *   conn.commit();手动提交;
 *   conn,rollback();手动回滚；
 *  测试pull
 */
public class JDBCTest04 {
    public static void main(String[] args) {
        Connection conn=null;
        PreparedStatement ps=null;
        try {
            //1、注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2、获取连接
            conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/jdbc", "root", "root");
            //拿到连接对象后立即开启事务。开启事务：将自动提交机制关闭掉
            //void setAutoCommit(boolen autoCommit) throws SQLException
            // 参数autoCommit为true表示启动自动提交模式，为false表示禁用自动提交模式
            conn.setAutoCommit(false);

            //3、获取预编译的数据库操作对象

            String sql=" update t_act set balance =? where actno= ?";
            ps=conn.prepareStatement(sql);
            //给?传值
            ps.setDouble(1,10000);
            ps.setString(2,"A");
            int count=ps.executeUpdate();
            //模拟异常（验证回滚）
            //String s=null;
            //s.toString();//空指针异常

            //给？传值
            ps.setDouble(1,10000);
            ps.setString(2,"B");
            count+=ps.executeUpdate();

            System.out.println(count==2?"转账成功":"转账失败");
            //代码能执行到此处，说明上面的代码没有出现任何异常，表示都成功了，手动提交
            //手动提交，事务结束。
            conn.commit();

        } catch (Exception e) {
            //出现异常的话，为了保险起见，这里要回滚！

            try {
                if(conn!=null){
                    conn.rollback();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }

            e.printStackTrace();
        }finally {
            //6、释放资源
            if(ps!=null){

                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }


    }
}
